package com.suning.sawp.web.filter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Charsets;
import com.suning.ids.client.AuthenticationFilter;
import com.suning.ids.client.config.Configuration;
import com.suning.ids.client.principal.IdsPrincipal;
import com.suning.ids.client.storage.StorageAccessor;
/**
 * 
 * 内部passport包装filter<br> 
 * 〈功能详细描述〉
 *
 * @author 12061818
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
public class StaffPassportFilter implements Filter {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(StaffPassportFilter.class);

    /**
     * 校验VOIP的登录准入鉴权的权限URL
     */
    private static final String VALID_VOIP_URL = "/sawp/sys/validVoipUser.do";
    
    private static final String AUTHENTICATION_URL_PATTERN_PARAM = "authUrlPattern";

    private static final String DEFAULT_AUTHENTICATION_URL_PATTERN = "/auth";

    private static final String AUTH_STATUS_URL_PATTERN_PARAM = "authStatusUrlPattern";

    private static final String DEFAULT_AUTH_STATUS_URL_PATTERN = "/authStatus";

    private static final String POPUP_LOGIN_SUCCESS_URL_PATTERN_PARAM = "popupLoginSuccessUrlPattern";

    private static final String DEFAULT_POPUP_LOGIN_SUCCESS_URL_PATTERN = "/popupLoginSuccess";
    
    private ServletContext sc;
    
    private List<String> ignorePatternList = new ArrayList<String>();
    
    /**
     * 内部passport的filter
     */
    private AuthenticationFilter authenticationFilter;
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        sc = filterConfig.getServletContext();
        authenticationFilter = new AuthenticationFilter();
        authenticationFilter.init(filterConfig);
        
        String authServletUrlPattern = filterConfig.getInitParameter(AUTHENTICATION_URL_PATTERN_PARAM);
        if (StringUtils.isEmpty(authServletUrlPattern)) {
            authServletUrlPattern = DEFAULT_AUTHENTICATION_URL_PATTERN;
        }
        ignorePatternList.add(authServletUrlPattern);
        String authStatusServletUrlPattern = filterConfig.getInitParameter(AUTH_STATUS_URL_PATTERN_PARAM);
        if (StringUtils.isEmpty(authStatusServletUrlPattern)) {
            authStatusServletUrlPattern = DEFAULT_AUTH_STATUS_URL_PATTERN;
        }
        ignorePatternList.add(authStatusServletUrlPattern);
        String popupLoginSuccessUrlPattern = filterConfig.getInitParameter(POPUP_LOGIN_SUCCESS_URL_PATTERN_PARAM);
        if (StringUtils.isEmpty(popupLoginSuccessUrlPattern)) {
            popupLoginSuccessUrlPattern = DEFAULT_POPUP_LOGIN_SUCCESS_URL_PATTERN;
        }
        ignorePatternList.add(popupLoginSuccessUrlPattern);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        
        // 获取根目录所对应的绝对路径:
        String currentURI = httpRequest.getRequestURI();
        LOGGER.debug("InnerPassportFilter currentURI：{}", currentURI);
        if (VALID_VOIP_URL.equals(currentURI)) {
            // 如果是校验VIOP的URL请求，key即为cookie中的authId，校验通过响应状态码200，其他都为400
            String reqBody = getInputString(httpRequest); 
            String key = null;
            String userId = null;
            if (StringUtils.isNotBlank(reqBody)) {
                JSONObject jsonObject = JSONObject.parseObject(reqBody);
                key = jsonObject.getString("key");
                userId = jsonObject.getString("userId");
            }
            if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(userId)) {
                Configuration configuration = Configuration.getInstance(this.sc);
                // 取passport中对应的工号
                StorageAccessor storageAccessor = configuration.getStorageAccessor();
                IdsPrincipal principal = storageAccessor.getPrincipal(key);
                if (null != principal && !principal.isAnonymous()
                        && userId.equals(principal.getName())) {
                    // 传过来的AuthId，passport校验通过，并且passport的工号与传入的userId一致则表示VOIP校验用户通过
                    httpResponse.sendError(HttpServletResponse.SC_OK);
                    return;
                } else {
                    httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST);
                    return;
                }
            } else {
               httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST);
               return;
            }
        }
        
        // 走passport正常filter
        authenticationFilter.doFilter(request, response, chain);
        return;
    }

    /**
     * 
     * 功能描述: 读取request报文<br>
     * 〈功能详细描述〉
     *
     * @param request
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private String getInputString(HttpServletRequest request) {
        InputStream inputStream = null;
        InputStreamReader  reader = null;
        BufferedReader  buffer = null;
        StringBuilder data = new StringBuilder();
        try{
            inputStream = request.getInputStream();
            reader = new InputStreamReader(inputStream, Charsets.UTF_8);
            buffer = new BufferedReader(reader);
            String tmp = null;
            while((tmp=buffer.readLine()) != null){
                data.append(tmp);
            }
            
            return data.toString();
        }catch (IOException e) {
            LOGGER.error("read request exception:",e);
        }finally{
            try {            
                if(buffer!=null){
                    buffer.close();
                }
                if(reader!=null){
                    reader.close();
                }
                if(inputStream!=null){
                    inputStream.close();
                }
            } catch (IOException e) {
                LOGGER.error("close exception:",e);
            }                
        }

        return null;
    }
    
    @Override
    public void destroy() {
        
    }

}
